package org.bronycorps.mlptss.domain.actor;

import org.bronycorps.mlptss.domain.controller.AbstractController;
import org.bronycorps.mlptss.domain.controller.BonusController;
import org.bronycorps.mlptss.domain.model.AbstractActorModel;
import org.bronycorps.mlptss.domain.model.Bonus;
import org.bronycorps.mlptss.domain.model.Bonus.BonusType;
import org.bronycorps.mlptss.domain.model.event.StateChangeEvent;
import org.bronycorps.mlptss.domain.model.event.StateChangeEventListener;
import org.bronycorps.mlptss.manager.preferences.GameConfiguration;
import org.bronycorps.mlptss.utils.AnimationCache;
import org.bronycorps.mlptss.utils.DrawableAnimation;

import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.ui.Image;

public class BonusActor extends AbstractGroupActor implements
		StateChangeEventListener {

	private BonusController bonusActor;

	private DrawableAnimation bubbleAnimation;
	private Image bubbleImage;
	private float currentBubbleTime;
	private DrawableAnimation moneyAnimation;
	private DrawableAnimation powerAnimation;

	public BonusActor(BonusController bonus) {
		super();
		this.bonusActor = bonus;
		this.bonusActor.getModel().addListener(this);

		createAnimation();

		this.bubbleImage.setDrawable(this.bubbleAnimation
				.getDrawableKeyFrame(this.currentBubbleTime));

		final Vector2 origin = this.bubbleAnimation.getOrigin();

		this.bubbleImage.setWidth(this.bubbleImage.getPrefWidth());
		this.bubbleImage.setHeight(this.bubbleImage.getPrefHeight());

		this.mainImage.setDrawable(this.currentAnimation
				.getDrawableKeyFrame(this.currentTime));
		this.mainImage.setWidth(this.mainImage.getPrefWidth());
		this.mainImage.setHeight(this.mainImage.getPrefHeight());
		this.mainImage.setX(origin.x - this.currentAnimation.getOrigin().x);
		this.mainImage.setY(origin.y - this.currentAnimation.getOrigin().y);

		this.hitBox.setWidth(getBounds().width);
		this.hitBox.setHeight(getBounds().height);

		setWidth(this.bubbleImage.getWidth());
		setHeight(this.bubbleImage.getHeight());
		setOriginX(origin.x);
		setOriginY(origin.y);

	}

	@Override
	public void act(float delta) {
		super.act(delta);
		this.currentBubbleTime += delta;
	}

	private void createAnimation() {

		String containerAnimName = GameConfiguration.getInstance()
				.getCurrentMod().getAssetsConfiguration().getBonus()
				.getContainerAnimation();
		this.bubbleAnimation = AnimationCache.getInstance().get(
				containerAnimName);

		String moneyAnimName = GameConfiguration.getInstance().getCurrentMod()
				.getAssetsConfiguration().getBonus().getMoneyAnimation();
		this.moneyAnimation = AnimationCache.getInstance().get(moneyAnimName);

		String powerAnimName;
		if (this.bonusActor.getModel().getBonusType() == BonusType.BOMB) {
			powerAnimName = GameConfiguration.getInstance().getCurrentMod()
					.getAssetsConfiguration().getBonus().getBombAnimation();
		} else {
			powerAnimName = GameConfiguration.getInstance().getCurrentMod()
					.getAssetsConfiguration().getBonus()
					.getShieldBreakerAnimation();
		}
		this.powerAnimation = AnimationCache.getInstance().get(powerAnimName);

		this.currentAnimation = getBonusModel().isMoney() ? this.moneyAnimation
				: this.powerAnimation;
	}

	@Override
	protected void drawFrame() {
		super.drawFrame();
		this.bubbleImage.setDrawable(this.bubbleAnimation
				.getDrawableKeyFrame(this.currentBubbleTime));
	}

	public Bonus getBonusModel() {
		return this.bonusActor.getModel();
	}

	@Override
	protected AbstractController getController() {
		return this.bonusActor;
	}

	@Override
	public AbstractActorModel getModel() {
		return this.bonusActor.getModel();
	}

	@Override
	protected Vector2 getModelOrigin() {
		return this.bubbleAnimation.getOrigin();
	}

	@Override
	protected Vector2 getModelPosition() {
		return this.bonusActor.getModel().getPosition();
	}

	@Override
	protected void initializeChildren() {
		super.initializeChildren();
		this.bubbleImage = new Image();

		addActor(this.bubbleImage);
	}

	@Override
	public void onStateChange(StateChangeEvent event) {
		switchAnimation((getBonusModel().isMoney() ? this.moneyAnimation
				: this.powerAnimation));
	}

	@Override
	protected void switchAnimation(DrawableAnimation nextAnimation) {

		// reset animation's timer
		this.currentTime = 0;
		this.currentBubbleTime = 0;
		// change the animation
		this.currentAnimation = nextAnimation;
		drawFrame();

		this.mainImage.setX(getModelOrigin().x
				- this.currentAnimation.getOrigin().x);
		this.mainImage.setY(getModelOrigin().y
				- this.currentAnimation.getOrigin().y);
	}

	@Override
	protected void updateHitbox() {
		Rectangle bounds = getBounds();
		this.hitBox.x = getX() + getOriginX() - getScaleX()
				* (this.currentAnimation.getOrigin().x - bounds.x);
		this.hitBox.y = getY() + getOriginY() - getScaleY()
				* (this.currentAnimation.getOrigin().y - bounds.y);

		getRelativeHitBox();
	}
}
